﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using BrainTechLLC.ThreadSafeObjects;
using System.Threading;
#if USE_HYPER
using Hyper.ComponentModel;
#endif

namespace BrainTechLLC
{
#if NO_SILVERLIGHT
    //[TypeDescriptionProvider(typeof(HyperTypeDescriptionProvider))]
#endif
    [DataContract]
    [Serializable]
#if NO_SILVERLIGHT
    [Browsable(true)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    [EditorBrowsable(EditorBrowsableState.Always)]
#endif
    public class AssociatedIDCollection : ThreadSafeLookupNonRef<long, long>, IAssociatedIDCollection, IEnumerable, INotifyCollectionChanged
    {        
        public AssociatedIDCollection() { }
        public AssociatedIDCollection(params long[] ids)
        {
            foreach (long id in ids)
                Add(id);
        }

        public static implicit operator AssociatedIDCollection(long id)
        {
            return new AssociatedIDCollection(id);
        }

        public List<long> AllIDs
        {
            get { return AllItems; }
        }

        public bool Contains(long id)
        {
            return Lookup.ContainsKey(id);
        }

        public bool AddMultiple(IList<long> items)
        {
            return AddMultiple(items, items);
        }

        public bool Add(long id)
        {
            return Add(id, id);
        }

        public List<IAssociatedID> AllGameThingsInCollection
        {
            get
            {
                return ReadItems<IAssociatedID>();
            }
        }

        public List<T> ReadItems<T>() where T : class, IAssociatedID
        {
            List<T> results = new List<T>();
            AllItems.ForEach((id) =>
            {
                var thing = Everything.Find<T>(id);
                if (thing != null)
                    results.Add(thing);
            });
            return results;
        }

        public List<T> ReadItems<T>(Func<T, bool> match) where T : class, IAssociatedID
        {
            List<T> results = new List<T>();
            AllItems.ForEach(
                 (id) =>
                 {
                     T thing = Everything.Find<T>(id);

                     if (thing != null && match(thing))
                         results.Add(thing);
                 });
            return results;
        }

        public T FindFirst<T>(Func<T, bool> match) where T : class, IAssociatedID
        {
            for (int n = 0; n < AllItems.Count; n++)
            {
                T thing = Everything.Find<T>(AllItems[n]);

                if (thing != null && match(thing))
                    return thing;
            }

            return null;
        }


        protected AssociatedIDCollection MakeCopy()
        {
            AssociatedIDCollection collection = new AssociatedIDCollection();
            collection.AddMultiple(AllIDs);
            return collection;
        }        
    }
}